package com.gree.syq.wifidemo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.net.NetworkInterface;
import java.util.Collections;
import java.util.List;

import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;

public class AirConditionRole extends DemoRole {
    private final static String TAG = "AirConditionRole";
    private final ConnectivityManager mConnManager;
    private final WifiManager mWifiManager;
    private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
    private static String addr = "persist.wifidemo.addr";

    private static AirConditionRole sAirConditionState = null;
    private Context mContext;
    private String mMsg = "Aircondition";

    private Handler handler = new Handler();
    private HandlerThread mHandlerThread = new HandlerThread("Air");
    private Handler mStateHandler;
    private static class doSomeThing {
        private doSomeThing() {

        }

        public static final int SEND_DEVICE_STATE = 0;
        public static final int PREPARE_CONFIG_NETWORK = 1;
        public static final int CONFIG_NETWORK = 2;

    }
    private DemoState mState = new DemoState() {
        @Override
        public void run(Message msg) {
            mState = mCanConfigState;
        }
    };



    private Runnable mRecoverIdleState = new Runnable() {
        @Override
        public void run() {
            mState = mCanConfigState;
            updateButton();
        }
    };

    private DemoState mIdleState = new DemoState() {
        @Override
        public void run(Message msg) {
            switch (msg.what) {
                case doSomeThing.SEND_DEVICE_STATE:
                    sendDeviceState();
                    break;
                case doSomeThing.PREPARE_CONFIG_NETWORK:
                    mState = mCanConfigState;
                    updateButton();
                    mStateHandler.postDelayed(mRecoverIdleState,120 * 1000);
                    break;
                default:
                    break;
            }
        }
    };

    private DemoState mCanConfigState = new DemoState() {
        @Override
        public void run(Message msg) {
            switch (msg.what) {
                case doSomeThing.SEND_DEVICE_STATE:
                    sendDeviceState();
                    break;
                case doSomeThing.CONFIG_NETWORK:
                    String ssid = msg.getData().getString("ssid","");
                    String pwd = msg.getData().getString("password","");
                    int type = msg.getData().getInt("type",0);
                    setNetwork(ssid,pwd,type);
                    mState = mCanConfigState;
                    updateButton();
                    mStateHandler.removeCallbacks(mRecoverIdleState);
                    break;
                default:
                    break;
            }
        }
    };

    private Button buttonUp;
    private Button buttonDown;
    private Activity activity;

    private Runnable keepRun = new Runnable() {
        @Override
        public void run() {
            sendDeviceState();
            mStateHandler.postDelayed(this,10000);
        }
    };

    private void updateButton(){
        Runnable updateButtonRunnable = new Runnable() {
            @Override
            public void run() {
                if (mState.equals(mCanConfigState)) {
                    buttonUp.setText("准备配网");
                } else {
                    if (isWifiConnect()) {
                        buttonUp.setText("已连接网络");
                    } else {
                        buttonUp.setText("未连接网络");
                    }
                }
            }
        };
        //handler.post(updateButtonRunnable);
    }

    public static AirConditionRole getInstance(Context context) {
        if (sAirConditionState == null) {
            sAirConditionState = new AirConditionRole(context);
        }
        return sAirConditionState;
    }

    protected AirConditionRole(Context context) {
        mContext = context;
        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        mConnManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        mHandlerThread.start();
        mStateHandler = new Handler(mHandlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                mState.run(msg);
            }
        };
        init();
    }

    private boolean isWifiConnect() {
        NetworkInfo mWifiInfo = mConnManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        return mWifiInfo.isConnected();
    }

    @Override
    public void init(Activity activity) {
        init();
        mState = mCanConfigState;
        this.activity = activity;
        buttonUp = (Button) activity.findViewById(R.id.remoteButton);
        buttonDown = (Button) activity.findViewById(R.id.ariconditionButton);


        buttonUp.setEnabled(false);
        updateButton();

        buttonDown.setText("允许配网");
        buttonDown.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mStateHandler.sendEmptyMessage(doSomeThing.PREPARE_CONFIG_NETWORK);
            }
        });
        buttonDown.setEnabled(true);
    }

    @Override
    public void init() {
        if(isWifiConnect()) {
            mState = mCanConfigState;
        } else {
            mState = mCanConfigState;
        }
        mStateHandler.post(keepRun);
    }

    @Override
    public void run(String para) {
        Log.i(TAG, "run: " + para);
        int indexSSID = 0;
        int indexPWD = 0;

        if (!para.startsWith("SYQ")) {
            return;
        }

        for (int i = 3; i < para.length(); i++) {
            if (para.charAt(i) == '/') {
                indexSSID = i;
                break;
            }
        }

        for (int i = indexSSID + 1; i < para.length(); i++) {
            if (para.charAt(i) == '/') {
                indexPWD = i;
                break;
            }
        }

        List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();

        String SSID = para.substring(3, indexSSID);
        String preSharedKey = para.substring(indexSSID + 1, indexPWD);
        String Encryp = para.substring(indexPWD + 1, para.length());
        WifiCipherType Type = WifiCipherType.WIFICIPHER_NOPASS;

        for (WifiConfiguration configuration : wifiConfigurationList) {
            if (configuration.SSID != null) {
                if (configuration.SSID.equals("\"" + SSID + "\"")) {
                    return;
                }
            }
        }

        switch (Encryp) {
            case "NONE":
                Type = WifiCipherType.WIFICIPHER_NOPASS;
                break;
            case "WPA-PSK":
                Type = WifiCipherType.WIFICIPHER_WPA;
                break;
            case "WPA-EAP":
                Type = WifiCipherType.WIFICIPHER_WEP;
                break;
            default:
                break;
        }

        DemoLog.getInstance().logi("SSID: " + SSID);
        DemoLog.getInstance().logi("PWD: " + preSharedKey);
        DemoLog.getInstance().logi("TYPE: " + Encryp);
        WifiConfiguration wifiConfiguration = createWifiInfo(SSID, preSharedKey, Type);

        mWifiManager.addNetwork(wifiConfiguration);
        mWifiManager.connect(wifiConfiguration, null);
    }

    public void setNetworkNative(String ssid, String pwd, int type){
        Message msg = mStateHandler.obtainMessage(doSomeThing.CONFIG_NETWORK);
        Bundle bundle = new Bundle();
        bundle.putString("ssid",ssid);
        bundle.putString("password",pwd);
        bundle.putInt("type",type);
        msg.setData(bundle);
        mStateHandler.sendMessage(msg);
    }

    private void setNetwork(String ssid, String pwd, int type) {
        List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();

        for (WifiConfiguration configuration : wifiConfigurationList) {
            if (configuration.SSID != null) {
                if (configuration.SSID.equals("\"" + ssid + "\"")) {
                    return;
                }
            }
        }

        WifiConfiguration wifiConfiguration = createWifiInfo(ssid, pwd, WifiCipherType.values()[type]);

        mWifiManager.addNetwork(wifiConfiguration);
        mWifiManager.connect(wifiConfiguration, null);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {

        } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {

            // request available peers from the wifi p2p manager. This is an
            // asynchronous call and the calling activity is notified with a
            // callback on PeerListListener.onPeersAvailable()
            mPeers = (WifiP2pDeviceList) intent.getParcelableExtra(
                    WifiP2pManager.EXTRA_P2P_DEVICE_LIST);
            for (WifiP2pDevice device : mPeers.getDeviceList()) {
                Log.d(TAG, "P2P peers changed: " + device.deviceName);
                //this.run(device.deviceName);
                DemoRole.doCommand(device.deviceName);
            }
        } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {


        } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {


        } else if (CONNECTIVITY_ACTION.equals(action)) {
            updateButton();
            DemoLog.getInstance().logi("Connected");
        }
    }

    private WifiConfiguration createWifiInfo(String SSID, String Password, WifiCipherType Type) {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + SSID + "\"";
// nopass
        if (Type == WifiCipherType.WIFICIPHER_NOPASS) {
            config.wepKeys[0] = "";
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        }
// wep
        if (Type == WifiCipherType.WIFICIPHER_WEP) {
            if (!TextUtils.isEmpty(Password)) {
                config.wepKeys[0] = "\"" + Password + "\"";
            }
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        }
// wpa
        if (Type == WifiCipherType.WIFICIPHER_WPA) {
            config.preSharedKey = "\"" + Password + "\"";
            config.hiddenSSID = true;
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
// 此处需要修改否则不能自动重联
// config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            config.status = WifiConfiguration.Status.ENABLED;
        }
        return config;
    }

    @Override
    public void unRegister() {
        super.unRegister();
    }

    void onDeviceState() {
        mStateHandler.sendEmptyMessage(doSomeThing.SEND_DEVICE_STATE);
    }

    void sendDeviceState() {
        MessageP2P.getInstance(mContext).clearDeviceStateCommand();
        int addr = Integer.parseInt(SystemProperties.get(this.addr,"255"));

        if (isWifiConnect()) {
            MessageP2P.getInstance(mContext).sendDeviceStateCommand(2,addr);
        } else {
            MessageP2P.getInstance(mContext).sendDeviceStateCommand(1,addr);
        }

    }
}
